home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / gnome-games-data / glchess / ggz / chess.py < prev    next >
Encoding:
Python Source  |  2009-04-14  |  5.4 KB  |  176 lines

  1. # -*- coding: utf-8 -*-
  2. import struct
  3.  
  4. class GGZChessFeedback:
  5.             
  6.     def onSeat(self, seatNum, version):
  7.         pass
  8.             
  9.     def onPlayers(self, whiteType, whiteName, blackType, blackName):
  10.         pass
  11.                 
  12.     def onClockRequest(self):
  13.         pass
  14.     
  15.     def onClock(self, mode, seconds):
  16.         pass
  17.  
  18.     def onStart(self):
  19.         pass
  20.     
  21.     def onMove(self, move):
  22.         pass
  23.  
  24. class Chess:
  25.     
  26.     CLOCK_NONE      = 0
  27.     CLOCK_CLIENT    = 1
  28.     CLOCK_SERVERLAG = 2
  29.     CLOCK_SERVER    = 3
  30.     
  31.     # Player codes (copied from GGZ_SEAT_*)
  32.     GGZ_SEAT_NONE      = '\x00' # This seat does not exist */
  33.     GGZ_SEAT_OPEN      = '\x01' # The seat is open (unoccupied).
  34.     GGZ_SEAT_BOT       = '\x02' # The seat has a bot (AI) in it.
  35.     GGZ_SEAT_PLAYER    = '\x03' # The seat has a regular player in it.
  36.     GGZ_SEAT_RESERVED  = '\x04' # The seat is reserved for a player.
  37.     GGZ_SEAT_ABANDONED = '\x05' # The seat is abandoned by a player.
  38.  
  39.     def sendClock(self, mode, seconds):
  40.         return '\x04' + struct.pack('!I', (mode << 24) | (seconds & 0x00FFFFFF))
  41.  
  42.     def sendMove(self, move, time = None):
  43.         cmd = '\x06' + struct.pack('!I', len(move)) + move
  44.         if time is not None:
  45.             cmd += struct.pack('!I', time)
  46.         return cmd
  47.     
  48.     def sendStart(self):
  49.         return '\x05'
  50.  
  51.     def __init__(self, feedback):
  52.         self.feedback = feedback
  53.  
  54.         self.decodeMethod = None
  55.         self.decodeMethods = {'\x01': self.decodeSeat,
  56.                               '\x02': self.decodePlayers,
  57.                               '\x03': self.decodeClockRequest,
  58.                               '\x04': self.decodeClock,
  59.                               '\x05': self.decodeStart,
  60.                               # 6: Move request
  61.                               '\x07': self.decodeMove,
  62.                               '\x08': self.decodeGameEnd,
  63.                               #9: Update request
  64.                               '\x0a': self.decodeUpdate,
  65.                               #11: server time update?
  66.                               #12: self.decodeFlag,
  67.                               '\x0d': self.decodeDraw}
  68.  
  69.     def decode(self, char):
  70.         if self.decodeMethod is None:
  71.             try:
  72.                 self.decodeMethod = self.decodeMethods[char]
  73.             except KeyError:
  74.                 self.decodeMethod = None
  75.                 print 'Unknown data received: %s' % repr(char)                
  76.                 return
  77.             self.command = ''
  78.         self.command += char
  79.         self.decodeMethod()
  80.         
  81.     def getGGZString(self, buffer):
  82.         if len(buffer) < 4:
  83.             return (None, 0)
  84.         (length,) = struct.unpack("!I", buffer[:4])
  85.         if len(buffer) < length + 4:
  86.             return (None, 0)
  87.         
  88.         string = buffer[4:length + 4]
  89.         
  90.         # Strip C null characters
  91.         while string.endswith('\x00'):
  92.             string = string[:-1]
  93.         
  94.         return (string, length + 4)
  95.  
  96.     def decodeSeat(self):
  97.         # seat [01][num][version]
  98.         if len(self.command) == 3:
  99.             self.decodeMethod = None
  100.             (num, version) = struct.unpack('!xBB', self.command)
  101.             self.feedback.onSeat(num, version)
  102.     
  103.     def decodePlayers(self):
  104.         # players [02][code1][name1(18)][code2][name2(18)]
  105.         # name is ommitted if code == 01 (open)
  106.         requiredLength = 2
  107.         if len(self.command) < requiredLength:
  108.             return
  109.         
  110.         whiteCode = self.command[1]
  111.         if whiteCode == self.GGZ_SEAT_OPEN:
  112.             requiredLength += 1
  113.             whiteName = ''
  114.         else:
  115.             (whiteName, offset) = self.getGGZString(self.command[requiredLength:])
  116.             if whiteName is None:
  117.                 return
  118.             requiredLength += 1 + offset
  119.         if len(self.command) < requiredLength:
  120.             return
  121.  
  122.         blackCode = self.command[requiredLength - 1]
  123.         if blackCode == self.GGZ_SEAT_OPEN:
  124.             blackName = ''
  125.         else:
  126.             (blackName, offset) = self.getGGZString(self.command[requiredLength:])
  127.             if blackName is None:
  128.                 return
  129.             requiredLength += offset
  130.  
  131.         if len(self.command) >= requiredLength:
  132.             self.decodeMethod = None
  133.             self.feedback.onPlayers(whiteCode, whiteName, blackCode, blackName)
  134.     
  135.     def decodeClockRequest(self):
  136.         # [3]
  137.         self.decodeMethod = None
  138.         self.feedback.onClockRequest()
  139.         
  140.     def decodeClock(self):
  141.         # [4][mode][seconds]
  142.         if len(self.command) == 5:
  143.             (value,) = struct.unpack("!xI", self.command)
  144.             mode = value >> 24
  145.             seconds = value & 0x00FFFFFF
  146.             self.feedback.onClock(mode, seconds)
  147.             self.decodeMethod = None
  148.         
  149.     def decodeStart(self):
  150.         # [5]
  151.         self.decodeMethod = None
  152.         self.feedback.onStart()
  153.  
  154.     def decodeMove(self):
  155.         #    [07][move(8)]
  156.         # or [07][move(8)][seconds]
  157.         (move, _) = self.getGGZString(self.command[1:])
  158.         if move is None:
  159.             return
  160.         self.decodeMethod = None
  161.         self.feedback.onMove(move)
  162.             
  163.     def decodeGameEnd(self):
  164.         # [08][result]
  165.         if len(self.command) == 2:
  166.             self.decodeMethod = None
  167.  
  168.     def decodeUpdate(self):
  169.         # [0A][wtime][btime]
  170.         if len(self.command) == 9:
  171.             self.decodeMethod = None
  172.             
  173.     def decodeDraw(self):
  174.         # [0D]
  175.         self.decodeMethod = None
  176.